//------------------ģ��˵��---------------
//��ģ������оƬΪDMX512������汾
//-----------------------------------------
module out_ctrl_DMX512_ACK(
                input	wire		resetb,
		input   wire            sclk,
		input   wire            out_clk,
		
		input	wire		set_d_ok,
		input	wire	[15:0]	set_addr,
		input	wire	[7:0]	set_data,
		
		input	wire		ext_d_ok,
		input	wire	[15:0]	ext_addr,

		input	wire		t_ms,	
		input   wire            t_s,
		input   wire            t_us,
		
		input	wire	[7:0]	state_2,
		input	wire	[1:0]	color_restore_type,
		input	wire	[7:0]	led_light,
		
		input   wire	[7:0]	chip_type,
		input	wire	[9:0]	div_count_max,
		input	wire	[9:0]	clock_low_time,
		input	wire	[9:0]	div_cnt,		
		input   wire	[9:0]	port_l_unit,
		input   wire	[7:0]	shift_length_per_unit,
		input   wire	[15:0]	config_d,
		input	wire	[7:0]	config_custom,

		input   wire            out_en,
		input   wire            vsin,
		output 	reg		vsout,

		//display_data buf
		output  reg             read_pixel_first,
		output  reg             read_pixel_req,
		output	reg	[7:0]	read_pixel_addr,
		output  reg	[9:0]	read_unit_addr,
		output  reg             data_load_req,
		output  wire		data_shift_req,
		output  reg		r_shift_req,
		output  reg	[3:0]	data_bit_sel,
		input   wire    [7:0]   data_bit,
		        
 		//DMX输出信号
		output	wire	[1:0]	dmx_mode,
		output  reg		dmx_rec_en,
		output	reg	[7:0]	out_data_dmx,
 		//DMX写址信号
 		output	wire		pin4_w_active,
		output	wire	[2:0]	waddr_mode,
		output	wire	[7:0]	waddr_data,
		
 		//DMXACK5034模式标志
		output 	wire		custom_map,
		
 		//DMX反馈控制
		output  wire		mem_err_sel,	//0:err�������̡�1:mem�������̡�
		output	reg	[2:0]	err_port_num,
		output	reg		err_read_start,
		output 	reg	[3:0]	mem_active_port,//0�����ж˿ڶ�ѡͨ��1~8��ʵ�ʶ�Ӧ��1~8�˿�
		output 	reg		mem_read_start,
		
		output	wire	[31:0]	tout		
		);
//******************************************************************/
//			   ��������
//******************************************************************/
parameter	Idle	        =12'b000000000001;
parameter	Wait_Vsin	=12'b000000000010;
parameter	Pre_State	=12'b000000000100;
parameter	Send_Head	=12'b000000001000;
parameter	Send_Data	=12'b000000010000;
parameter	Comdata_Pre	=12'b000000100000;
parameter	Send_Comdata	=12'b000001000000;	
parameter	Wait_Ackdata	=12'b000010000000;	
parameter	Send_Mem_Head	=12'b000100000000;	
parameter	Send_Mem_Data	=12'b001000000000;	
parameter	Send_Mem_Pre	=12'b010000000000;
parameter	W_DMX_Addr	=12'b100000000000;
parameter       Gray_Scale      =8;				   
//******************************************************************/
//			   �źŶ���
//******************************************************************/
reg		module_en;
reg     [11:0]   state;
reg		vsin_t,vsin_a;
reg		pre_end, head_end, last_bit, last_dot, last_chip, end_flag, send_end;
reg     [15:0]  pre_cnt;
reg     [10:0]  head_cnt;
reg	[3:0]	bit_cnt;
reg	[7:0]	dot_cnt;
reg	[10:0]	chip_cnt;
wire	[3:0]	bit_max, dot_length;
wire	[7:0]	dot_max;
wire	[9:0]	chip_max;
reg	[15:0]	pre_max;
reg		first_flag, data_en_t, pre_clk_en;
reg	[16:0]	data_en_shift;			
reg		out_clk_t, sync_1_flag, sync_d_flag, sync_0_flag;
reg	[9:0]	div_count;
reg	[7:0]	sss_data;
reg		sss;

reg		first_dot;
reg	[10:0]	break_time;
reg	[10:0]	mab_time;

//DMX_ACK
reg		cmd_send_flag,wait_ack_end,cmd_last_bit,cmd_last_data,cmd_send_end;
reg	[3:0]	cmd_bit_cnt;
reg	[7:0]	cmd_data_cnt;
reg             t_ms_d0,t_ms_d1,t_ms_d2;
reg	[5:0]	wait_ms_max;
reg	[2:0]	cmd_type;
reg	[5:0]	ms_cnt;
wire	[5:0]	cmd_data_max;
reg		dmxack_en;
reg		custom_map_en;
reg	[7:0]	cmd_data;
//DMX包发送
reg		dmx_w_actvie,w_icolor_flag,mem_send_req_sclk;
wire		mem_send_req,mem_head_end,mem_head_end_sclk;
reg	[2:0]	mem_head_end_t,mem_send_req_t;
reg	[7:0]	mem_len;
wire	[9:0]	mem_data_max;
reg		data_wea;
wire	[7:0]	data_addrb,data_doutb;
reg	[7:0]	mem_data;
reg		mem_addr_last;
reg	[7:0]	mem_data_cnt;

//mem_op
wire		mem_op_flag;

//mem_port
reg	[3:0]	mem_port_t1,mem_port_t2;
reg		send_realtime_status;

//
wire		mbi6027_ack_en;
reg		mem_pre_end;
reg	[7:0]	mem_pre_cnt;
wire		color_restore_receiver;

reg		us_cnt_en,us_cnt_en_t,us_cnt_en_tt;
reg		t_us_d0,t_us_d1,t_us_d2;
reg	[12:0]	us_cnt;
reg	[12:0]	us_max;
reg		wait_end_tt,wait_end_t;

reg		w_addr_en;
wire		w_addr_req,w_addr_end;
reg	[2:0]	w_addr_req_t,w_addr_en_t,w_addr_end_t;		

wire	[31:0]	addrw_tout;

wire		detail_info_en;
//******************************************************************/
//			   ����break_time��mab_time
//******************************************************************/
reg	[16:0]	t1;
reg	[16:0]	t2;
reg	[10:0]	t1_cnt,break_time_r;
reg	[10:0]	t2_cnt,mab_time_r;
always@(posedge sclk or negedge resetb)
	if(resetb==0)
		t1<=0;
	else if(t1[16]==1 || t1==0)
		t1<=60000;	//400us 400000/6.667=60000
	else
		t1<=t1-div_count_max;

always@(posedge sclk or negedge resetb)
	if(resetb==0)
		t2<=0;
	else if(t2[16]==1 || t2==0)
		t2<=4800;	//32us 32000/6.667=4800
	else
		t2<=t2-div_count_max;

always@(posedge sclk or negedge resetb)
	if(resetb==0)
		t1_cnt<=0;
	else if(t1[16]==1 || t1==0)
		t1_cnt<=0;
	else
		t1_cnt<=t1_cnt+1;

always@(posedge sclk or negedge resetb)
	if(resetb==0)
		t2_cnt<=0;
	else if(t2[16]==1 || t2==0)
		t2_cnt<=0;
	else
		t2_cnt<=t2_cnt+1;
			
always@(posedge sclk or negedge resetb)
	if(resetb==0)
		break_time<=0;
	else if(t1[16]==1 || t1==0)
		break_time<=t1_cnt;

always@(posedge sclk or negedge resetb)
	if(resetb==0)
		mab_time<=0;
	else if(t2[16]==1 || t2==0)
		mab_time<=t2_cnt;		

//always@(posedge out_clk)
//	begin
//		break_time<=break_time_r;
//		mab_time<=mab_time_r;
//	end
	
//******************************************************************/
//			   ͨѶ�ӿ�ʱ��������
//******************************************************************/
//DMX发送数据保存
always @(posedge sclk)
	if (ext_addr == 16'h20A0)
		dmx_w_actvie <= 1;
	else
		dmx_w_actvie <= 0;

always @( * )
	if(dmx_w_actvie == 0)
		data_wea <= 0;
	else
		data_wea <= ext_d_ok;

assign	data_addrb=mem_data_cnt;

swsr_256w8_256r8 mem_buf(
			.wrclock(sclk),
			.wren(data_wea),
			.wraddress(set_addr[7:0]),
			.data(set_data),
			.rdclock(out_clk),
			.rdaddress(data_addrb),
			.q(data_doutb)	
			);

//DMX包类型判断
always @(posedge sclk or negedge resetb)
	if(resetb==0)
		w_icolor_flag<=0;
	else if(dmx_w_actvie == 1 && ext_d_ok == 1 && set_addr[7:0] == 8'h00)
	begin
		if(set_data == 8'h5a)
			w_icolor_flag <= 1;
		else
			w_icolor_flag <= 0;
	end

//DMX包长度
always @(posedge sclk or negedge resetb)
	if(resetb==0)
		mem_len <= 0;
	else if(w_icolor_flag == 0)
		mem_len <= 255;
	else if(dmx_w_actvie == 1 && ext_d_ok == 1 && set_addr[7:0] == 8'h06)
		mem_len <= set_data;

//DMX包发送请求
always @(posedge sclk or negedge resetb)
	if(resetb==0)
		mem_send_req_sclk<=0;
	else if (dmx_w_actvie == 1 && ext_d_ok == 1 && set_addr[7:0] == 8'hFF)
		mem_send_req_sclk <= 1;
	else if (mem_head_end_sclk == 1)
		mem_send_req_sclk<=0;
		
//DMX包发送请求，转换时钟域到out_clk
always @(posedge out_clk)
	mem_send_req_t<={mem_send_req_t[1:0],mem_send_req_sclk};

assign	mem_send_req	=mem_send_req_t[2];

//DMX包发送响应，转换时钟域到sclk
assign	mem_head_end = state[8];

always @(posedge sclk)
	mem_head_end_t<={mem_head_end_t[1:0],mem_head_end};

assign	mem_head_end_sclk = mem_head_end_t[2];

//DMX端口选择
always @(posedge sclk)
	if (dmx_w_actvie == 1 && ext_d_ok == 1)
		mem_active_port <= set_addr[11:8];

//DMX端口选择，转换时钟域到out_clk
always @(posedge out_clk)
begin
	mem_port_t1<=mem_active_port;
	mem_port_t2<=mem_port_t1;
end

//其他信号
assign	mem_op_flag=state_2[2];// black_out_clk[2];
assign	mbi6027_ack_en=state_2[4];//

assign	mem_err_sel=mem_op_flag;			

//******************************************************************/
//			   ��������
//******************************************************************/
always @(posedge out_clk)
	if ( chip_type == 5 || chip_type == 27 || chip_type == 29 || chip_type == 28 || chip_type == 31)
		module_en <= 1;
	else
		module_en <= 0;

//always @(posedge out_clk or negedge resetb)
//	if(resetb==0)
//	begin
//		break_time	<=22;
//		mab_time	<=4;
//	end			
//	else if(chip_type == 27)	//WS2821,ʱ�ӿɱ䣬������ʱ��750k���㡣break��С88us,mab type = 8us
//	begin
//		break_time	<=66;
//		mab_time	<=6;
//	end	
//	else if(chip_type == 28)	//DMXACK 2M(mbi5034)��ʱ��2M�̶���break
//	begin
//		break_time	<=176;
//		mab_time	<=16;
//	end	
//	else if(chip_type == 29)	//DMX512AP,ʱ�ӿɱ䣬������500k���㣬break��С88us��mab��С8us
//	begin
//		break_time	<=44;
//		mab_time	<=4;
//	end		
//	else if(chip_type == 31)	//DMXACK  250k(mbi6027)��ʱ��250K�̶���break
//	begin
//		break_time	<=22;
//		mab_time	<=4;
//	end		
//	else
//	begin
//		break_time	<=22;	//��ͨDMX512�̶�ʱ��250K Ĭ��mab 16us
//		mab_time	<=4;
//	end	

always @(posedge out_clk)
//	if(chip_type == 28 || chip_type == 31)
//		send_realtime_status<=1;
//	else
		send_realtime_status<=0;
				
always @(posedge sclk)
	if(chip_type == 28 || chip_type == 31)
		dmxack_en<=1;
	else
		dmxack_en<=0;

assign	dmx_mode ={dmxack_en, module_en};

always @(posedge sclk)
	if(chip_type == 28)
		custom_map_en<=1;
	else
		custom_map_en<=0;

assign	custom_map = custom_map_en;

assign	bit_max = 7;
assign	dot_length = 11;

assign	dot_max = shift_length_per_unit;
assign	chip_max = port_l_unit;
//assign	pre_max = 5000;

always @(posedge out_clk)
	if (chip_type == 28)	//5034 ʱ��2M
		pre_max <= 1000;
	else			//6027 250k
		pre_max <= 125;
		
always @(cmd_type)
	case (cmd_type)
		1:	us_max <= 1500;
		2:	us_max <= 7500;
		3:	us_max <= 3000;
		default: us_max <= 3000;
	endcase

assign detail_info_en = 0;
assign cmd_data_max = 7;
assign mem_data_max = mem_len;//255;
assign color_restore_receiver=color_restore_type[1];
//***************************************************************/
//			    ����״̬����
//**************************************************************/
//**************************��״̬��****************************
always @(posedge out_clk or negedge resetb)
	if (resetb==0)
		state<=Idle;
	else if (module_en == 0)
		state<=Idle;
	else
		case (state)
			Idle:	
				if(out_en==1)
					state<=Wait_Vsin;
			Wait_Vsin:
				if(mem_send_req==1)
					state<=Send_Mem_Pre;
				else if(w_addr_req_t[2]==1)
					state<=W_DMX_Addr;
				else if (vsin_a == 1 && mem_op_flag == 0)
					state<=Pre_State;					
			Pre_State:
		               state<=Send_Head; 
			Send_Head:
				if (head_end == 1)
				begin
					if(cmd_send_flag==1)
						state<=Send_Comdata;
					else
						state<=Send_Data;
				end
			Send_Data:
				if (send_end == 1)
				begin
					if(send_realtime_status==1)
						state<=Comdata_Pre;
					else
						state<=Idle;
				end
			Comdata_Pre:
				if (pre_end==1)
					state<=Send_Head;
			Send_Comdata:
				if(cmd_send_end==1)
					state<=Wait_Ackdata;
			Wait_Ackdata:
				if(wait_ack_end==1)
					state<=Idle;
			W_DMX_Addr:
				if(w_addr_end_t[2]==1)			
					state<=Idle;
			Send_Mem_Pre:
				if(mem_pre_end==1)
					state<=Send_Mem_Head;
			Send_Mem_Head:
				if(head_end==1)
					state<=Send_Mem_Data;
			Send_Mem_Data:
				if(cmd_send_end==1)
					state<=Wait_Ackdata;
			default:	state<=Idle;
			
		endcase

//**************************DMXд��****************************
always@(posedge out_clk)
	if(state==W_DMX_Addr)
		w_addr_en<=1;
	else
		w_addr_en<=0;	

always@(posedge out_clk)begin
	w_addr_end_t	<={w_addr_end_t[1:0],w_addr_end};
	w_addr_req_t	<={w_addr_req_t[1:0],w_addr_req};
	end

always@(posedge sclk)
	w_addr_en_t	<={w_addr_en_t[1:0],w_addr_en};

dmx_addr_w_01 dmx_addr_w(
	.resetb(resetb),
        .sclk(sclk),    
			
        .set_d_ok(set_d_ok),    
        .set_addr(set_addr),    
        .set_data(set_data),

	.w_addr_req(w_addr_req),		//DMX写结束标志
	.w_addr_en(w_addr_en_t[2]),		//DMX写结束标志
	.w_addr_end(w_addr_end),		//DMX写结束标志

	.pin4_w_active(pin4_w_active),
	.waddr_data(waddr_data),
	.mode_write(waddr_mode),
	
	.tout(addrw_tout)
	);
		
//**************************�����ź�****************************
always @(posedge out_clk) begin
	vsin_t<=vsin;
	vsin_a<=vsin_t;
	end

always @(posedge out_clk) begin
	t_ms_d0<=t_ms;
	t_ms_d1<=t_ms_d0;
	t_ms_d2<=t_ms_d1; 
	end

always @(posedge out_clk)
	if (state !=  Comdata_Pre)	//�����⣬t_us��DMXʱ��Ƶ�ʹ������޷���׼
		pre_cnt <= 0;
	else //if(t_us_d2 == 0 && t_us_d1 == 1)
		pre_cnt <= pre_cnt+1;

always @(posedge out_clk)
	if (pre_cnt ==  pre_max)//)(t_us_d2 == 0 && t_us_d1 == 1 && pre_cnt ==  pre_max)
		pre_end <= 1;
	else
		pre_end <= 0;

always @(posedge out_clk)
	if (state !=  Send_Mem_Pre)	//�����⣬t_us��DMXʱ��Ƶ�ʹ������޷���׼
		mem_pre_cnt <= 0;
	else //if(t_us_d2 == 0 && t_us_d1 == 1)
		mem_pre_cnt <= mem_pre_cnt+1;

always @(posedge out_clk)
	if (mem_pre_cnt ==  pre_max)//)(t_us_d2 == 0 && t_us_d1 == 1 && pre_cnt ==  pre_max)
		mem_pre_end <= 1;
	else
		mem_pre_end <= 0;
		
always @(posedge out_clk)
	if (state !=  Send_Head && state != Send_Mem_Head)
		head_cnt <= 0;
	else
		head_cnt <= head_cnt + 1;

always @(posedge out_clk)
	if (head_cnt == break_time + mab_time - 1 - 1)
		head_end <= 1;
	else
		head_end <= 0;

always @(posedge out_clk)
	if (state !=  Send_Data)
		bit_cnt <= 0;
	else if (last_bit == 1)
		bit_cnt <= 0;
	else
		bit_cnt <= bit_cnt + 1;

always @(posedge out_clk)
	if (bit_cnt == dot_length - 2)
		last_bit <= 1;
	else
		last_bit <= 0;

always @(posedge out_clk)
	if (state !=  Send_Data)
		dot_cnt <= 0;
	else if (last_bit == 1) begin
		if (last_dot == 1)
			dot_cnt <= 0;
		else
			dot_cnt <= dot_cnt + 1;
		end

always @(posedge out_clk)
	if (dot_cnt == dot_max)
		last_dot <= 1;
	else
		last_dot <= 0;

always @(posedge out_clk)
	if (state==Send_Data &&  dot_cnt == 0)
		first_dot <= 1;
	else
		first_dot <= 0;
		
always @(posedge out_clk)
	if (state !=  Send_Data)
		chip_cnt <= 0;
	else if (last_bit == 1 && last_dot == 1)
		chip_cnt <= chip_cnt + 1;

always @(posedge out_clk)
	if (chip_cnt == chip_max+1)	
		last_chip <= 1;
	else
		last_chip <= 0;

always @(posedge out_clk)
	if (last_bit == 1 && first_dot ==1 && last_chip == 1)//����startռ��һ֡������Ҫ�෢8bit����
		send_end <= 1;
	else
		send_end <= 0;

//////////////send dmx cmd//////////////////////
always @(posedge out_clk or negedge resetb)
	if(resetb==0)
		cmd_type<=1;
	else if(state==Comdata_Pre)
	begin
		if(detail_info_en==1)	//������Ϣ
			cmd_type<=2;
		else 			//�ܵ�����Ϣ
			cmd_type<=1;	
	end
	else if(state==Send_Mem_Pre)
		cmd_type<=3;
	
always @(posedge out_clk or negedge resetb)
	if(resetb==0)
		cmd_send_flag<=0;
	else if(state==Comdata_Pre)
		cmd_send_flag<=1;
	else if(state==Wait_Ackdata)
		cmd_send_flag<=0;	

always @(posedge out_clk)
	if (state !=  Send_Comdata && state !=Send_Mem_Data)
		cmd_bit_cnt <= 0;
	else if (cmd_last_bit == 1)
		cmd_bit_cnt <= 0;
	else
		cmd_bit_cnt <= cmd_bit_cnt + 1;

always @(posedge out_clk)
	if (cmd_bit_cnt == dot_length - 2)
		cmd_last_bit <= 1;
	else
		cmd_last_bit <= 0;

always @(posedge out_clk)
	if (state !=  Send_Comdata && state !=Send_Mem_Data)
		cmd_data_cnt <= 0;
	else if (cmd_last_bit == 1) begin
		if (cmd_last_data == 1)
			cmd_data_cnt <= 0;
		else
			cmd_data_cnt <= cmd_data_cnt + 1;
		end

always @(posedge out_clk)
	if (state ==  Send_Comdata && cmd_data_cnt == cmd_data_max)
		cmd_last_data <= 1;
	else if (state ==  Send_Mem_Data && cmd_data_cnt == mem_data_max)
		cmd_last_data <= 1;
	else
		cmd_last_data <= 0;	

always @(posedge out_clk)
	if (cmd_bit_cnt == dot_length - 3)
		mem_addr_last <= 1;
	else
		mem_addr_last <= 0;
		
always @(posedge out_clk)
	if (state !=Send_Mem_Data)
		mem_data_cnt <= 0;
	else if (mem_addr_last == 1)
		mem_data_cnt <=mem_data_cnt+1;

reg	[7:0]	check_sum;
wire	[7:0]	check_sum0,check_sum1;
always @(posedge out_clk or negedge resetb)
	if(resetb==0)
		check_sum<=0;	
	else if(cmd_data_cnt==0)
		check_sum<=0;
	else 
		check_sum<=check_sum+cmd_data;

assign	check_sum0=check_sum;
assign	check_sum1=check_sum+1;
always @(posedge out_clk or negedge resetb)
	if(resetb==0)
		cmd_data<=0;
	else if (cmd_bit_cnt == 0)
	begin
		if(state==Send_Comdata)
			case(cmd_data_cnt)
			0:	cmd_data<=8'h5a;
			1:	cmd_data<=8'h0;
			2:	cmd_data<=8'h0;
			3:	cmd_data<=8'h1;
			4:	
				if(chip_type==28)
					cmd_data<=config_d[7:0];	//5034���ò���
				else
					cmd_data<=config_custom[7:0];	//�������Ƶ����۵�����
			5:	
				if(chip_type==28)
					cmd_data<=config_d[15:8];
				else if(color_restore_receiver==1)
					cmd_data<=led_light;
				else
					cmd_data<=8'hff;
			6:	cmd_data<=mbi6027_ack_en;
			7:	
				if(mbi6027_ack_en==1)
					cmd_data<=~check_sum1;
				else
					cmd_data<=~check_sum0;
			default:cmd_data<=0;
			endcase
		else if(state==Send_Mem_Data)
			cmd_data<=data_doutb;
	end
	else
		cmd_data<={1'b0,cmd_data[7:1]};
		
always @( * )
	if (cmd_last_bit == 1 && cmd_last_data == 1)
		cmd_send_end <= 1;
	else
		cmd_send_end <= 0;

////////////////////////////////////////////

always @(posedge out_clk)
	if (state ==  Wait_Ackdata)
		us_cnt_en <= 1;
	else
		us_cnt_en <=0;

always @(posedge sclk)
begin
	us_cnt_en_t	<=us_cnt_en;
	us_cnt_en_tt	<=us_cnt_en_t;
end

always @(posedge sclk) begin
	t_us_d0<=t_us;
	t_us_d1<=t_us_d0;
	t_us_d2<=t_us_d1; 
	end

always @(posedge sclk)
	if (us_cnt_en_tt==0)
		us_cnt <= 0;
	else if(t_us_d2 == 0 && t_us_d1 == 1 && us_cnt <  us_max)
		us_cnt <= us_cnt+1;

always @(posedge sclk)
	if(us_cnt_en_tt==0)
		wait_end_tt<=0;
	else if (t_us_d2 == 0 && t_us_d1 == 1 && us_cnt ==  us_max)
		wait_end_tt <= 1;
		
always @(posedge out_clk)
begin
	wait_end_t<=wait_end_tt;
	wait_ack_end<=wait_end_t;
end

always @(posedge out_clk)
	if (cmd_bit_cnt == 0)
		mem_data<=data_doutb;
	else
		mem_data<={1'b0,mem_data[7:1]};
//**************************************************************/
//			    ��memory
//**************************************************************/
always @*
	if (module_en == 0)
		data_bit_sel <= 0;
	else
		data_bit_sel <= 0;
		
always @*
	if (module_en == 0)
		read_pixel_addr <= 0;
	else
		read_pixel_addr <= dot_cnt;
		
always @*
	if (module_en == 0)
		read_unit_addr <= 0;
	else
		read_unit_addr <= chip_cnt;
		
always @(posedge out_clk)
	if ((state ==  Send_Data) && (bit_cnt == 0) && (send_end == 0))
		read_pixel_req <= 1;
	else
		read_pixel_req <= 0;
	
always @(posedge out_clk)
	if ((state !=  Send_Head) && (state !=  Send_Data))
		first_flag <= 0;
	else if (head_end ==  1)
		first_flag <= 1;
	else if (last_bit == 1)
		first_flag <= 0;
	
always @(posedge out_clk)
	if ((state ==  Send_Data) && (bit_cnt == 0) && (first_flag == 1))
		read_pixel_first <= 1;
	else
		read_pixel_first <= 0;
	
always @*
	if (last_bit == 1 && send_end==0)//last_chip == 0)
		data_load_req <= 1;
	else
		data_load_req <= 0;
		
assign	data_shift_req = 1'b0;

always @(posedge out_clk)
	if (state !=  Send_Data)
		r_shift_req <= 0;
	else if (data_load_req == 1) begin
		if (send_end == 0)
			r_shift_req <= 1;
		else
			r_shift_req <= 0;
		end
		
//**************************************************************/
//			    ����
//**************************************************************/
//��־������
always @(posedge out_clk)
	if (state == Send_Head)
		sss_data <= 8'h00;
	else
		sss_data <= {1'b0, sss_data[7:1]};

always @(posedge out_clk)
	sss <= sss_data[0];

always @(posedge out_clk)
	if (module_en == 0)
		out_data_dmx <= {8{1'b0}};
	else if(state==W_DMX_Addr)
		out_data_dmx <= {8{1'b1}};
	else if (state == Send_Head) begin
		if (head_cnt < break_time)
			out_data_dmx <= {8{1'b0}};
		else
			out_data_dmx <= {8{1'b1}};
		end
	else if (state == Send_Mem_Head) begin
		if (head_cnt < break_time)
		case(mem_port_t2)
			0:	out_data_dmx <={8{1'b0}};
			1:	out_data_dmx <={{7{1'b1}},1'b0};
			2:	out_data_dmx <={{6{1'b1}},1'b0,{1{1'b1}}};
			3:	out_data_dmx <={{5{1'b1}},1'b0,{2{1'b1}}};
			4:	out_data_dmx <={{4{1'b1}},1'b0,{3{1'b1}}};
			5:	out_data_dmx <={{3{1'b1}},1'b0,{4{1'b1}}};
			6:	out_data_dmx <={{2{1'b1}},1'b0,{5{1'b1}}};
			7:	out_data_dmx <={{1{1'b1}},1'b0,{6{1'b1}}};
			8:	out_data_dmx <={1'b0,{7{1'b1}}};
			default:out_data_dmx <={8{1'b0}};
		endcase
		else
			out_data_dmx <= {8{1'b1}};
		end
	else if (state == Send_Data && send_end==0) begin
		if (bit_cnt == 0)
			out_data_dmx <= {8{1'b0}};
		else if (bit_cnt > 8)
			out_data_dmx <= {8{1'b1}};
		else if (first_flag == 1)
			out_data_dmx <= {8{sss}};
		else
			out_data_dmx <= data_bit;
		end
	else if (state == Send_Comdata  && cmd_send_end==0) begin
		if (cmd_bit_cnt == 0)
			out_data_dmx <= {8{1'b0}};
		else if (cmd_bit_cnt > 8)
			out_data_dmx <= {8{1'b1}};
		else
			out_data_dmx <={8{cmd_data[0]}};
		end
	else if (state == Send_Mem_Data && cmd_send_end==0) begin
		if (cmd_bit_cnt == 0)
		case(mem_port_t2)
			0:	out_data_dmx <={8{1'b0}};
			1:	out_data_dmx <={{7{1'b1}},1'b0};
			2:	out_data_dmx <={{6{1'b1}},1'b0,{1{1'b1}}};
			3:	out_data_dmx <={{5{1'b1}},1'b0,{2{1'b1}}};
			4:	out_data_dmx <={{4{1'b1}},1'b0,{3{1'b1}}};
			5:	out_data_dmx <={{3{1'b1}},1'b0,{4{1'b1}}};
			6:	out_data_dmx <={{2{1'b1}},1'b0,{5{1'b1}}};
			7:	out_data_dmx <={{1{1'b1}},1'b0,{6{1'b1}}};
			8:	out_data_dmx <={1'b0,{7{1'b1}}};
			default:out_data_dmx <={8{1'b0}};
		endcase
			//out_data_dmx <= {8{1'b0}};
		else if (cmd_bit_cnt > 8)
			out_data_dmx <= {8{1'b1}};
		else
		case(mem_port_t2)
			0:	out_data_dmx <={8{cmd_data[0]}};
			1:	out_data_dmx <={{7{1'b1}},cmd_data[0]};
			2:	out_data_dmx <={{6{1'b1}},cmd_data[0],{1{1'b1}}};
			3:	out_data_dmx <={{5{1'b1}},cmd_data[0],{2{1'b1}}};
			4:	out_data_dmx <={{4{1'b1}},cmd_data[0],{3{1'b1}}};
			5:	out_data_dmx <={{3{1'b1}},cmd_data[0],{4{1'b1}}};
			6:	out_data_dmx <={{2{1'b1}},cmd_data[0],{5{1'b1}}};
			7:	out_data_dmx <={{1{1'b1}},cmd_data[0],{6{1'b1}}};
			8:	out_data_dmx <={cmd_data[0],{7{1'b1}}};
			default:out_data_dmx <={8{cmd_data[0]}};
		endcase
		end
	else
		out_data_dmx <= {8{1'b1}};
	
always @(posedge out_clk)
	if(state==Wait_Ackdata)
		dmx_rec_en<=1;
	//else if(state==Wait_Vsin && mem_op_flag==1)
	//	dmx_rec_en<=1;
	else
		dmx_rec_en<=0;

always @(posedge out_clk or negedge resetb)
	if(resetb==0)
		err_port_num<=0;
	else if(state==Comdata_Pre && pre_end==1)
		err_port_num<=err_port_num+1;

always @(posedge out_clk or negedge resetb)
	if(resetb==0)
		err_read_start <= 0;
	else if(state == Send_Comdata)
		err_read_start <= 1;
	else
		err_read_start <= 0;

always @(posedge out_clk or negedge resetb)
	if(resetb==0)
		mem_read_start<=0;
	else if(state==Send_Mem_Data)
		mem_read_start<=1;
	else
		mem_read_start<=0;
				
//***************SDRAM输出区切换信号**********************
always @(posedge out_clk)
	if(state==Wait_Vsin)
		vsout<=vsin_a;
	else
		vsout<=0;

//***********************************************
//		调试信号
//***********************************************
//assign	tout = {data_bit,t_us,r_shift_req,data_load_req,read_pixel_first,read_pixel_req,first_flag,send_end,end_flag,last_dot,last_chip,last_bit,out_clk,module_en,w_addr_end,w_addr_en,w_addr_req,state[11:0]};
assign	tout = {mem_port_t2,cmd_data[0],mem_send_req,state[11:0]};
//assign	tout = {w_addr_end,w_addr_en,w_addr_req,set_d_ok,sclk,set_data,set_addr};
//assign	tout = addrw_tout;

endmodule                